package net.sourceforge.openforecast;

import java.util.function.ToDoubleFunction;

/** A class of constants defining the various "evaluation criteria" that can be used to compare the accuracy of two
 * forecasting models. */
public enum EvaluationCriteria implements ToDoubleFunction<EvaluationModel> {
	/** EvaluationCriteria referring to the Akaike Information Criteria measure. */
	AIC("Akaike Information Citeria") {
		@Override
		public double applyAsDouble(EvaluationModel value) {
			return value.getAIC();
		}
	},

	/** EvaluationCriteria referring to Bias. */
	BIAS("Bias") {
		@Override
		public double applyAsDouble(EvaluationModel value) {
			return value.getBias();
		}
	},

	/** EvaluationCriteria referring to the Mean Absolute Deviation. */
	MAD("Mean Absolute Deviation") {
		@Override
		public double applyAsDouble(EvaluationModel value) {
			return value.getMAD();
		}
	},

	/** EvaluationCriteria referring to the Mean Absolute Percentage Error. */
	MAPE("Mean Absolute Percentage Error") {
		@Override
		public double applyAsDouble(EvaluationModel value) {
			return value.getMAPE();
		}
	},

	/** EvaluationCriteria referring to the Mean Squared Error. */
	MSE("Mean Squared Error") {
		@Override
		public double applyAsDouble(EvaluationModel value) {
			return value.getMSE();
		}
	},

	/** EvaluationCriteria referring to the Sum of the Absolute Error. */
	SAE("Sum Absolute Error") {
		@Override
		public double applyAsDouble(EvaluationModel value) {
			return value.getSAE();
		}
	},

	/** EvaluationCriteria referring to a reasonable blend of all other evaluation criteria. Rather than rely solely on
	 * one specific evaluation criteria to pick a "good" model, assess them all and select the model generally regarded
	 * as "better" by the majority of the criteria. */
	BLEND("Blend of Bias, MAD, MAPE, MSE, and SAE") {
		@Override
		public double applyAsDouble(EvaluationModel value) {
			throw new UnsupportedOperationException();
		}
	};

	public final String desc;

	private EvaluationCriteria(String desc) {
		this.desc = desc;
	}
}